<template>
  <div class="role">
    <!-- 上方搜索栏 -->
    <el-card class="search">
      <el-form :inline="true" class="form">
        <el-form-item label="用户名">
          <el-input placeholder="请输入要搜索的角色名" v-model="searchRoleName"></el-input>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="handleSearch">搜索</el-button>
          <el-button @click="handleReset">重置</el-button>
        </el-form-item>
      </el-form>
    </el-card>

    <!-- 下方角色列表 -->
    <el-card class="list">
      <!-- 上方按钮 -->
      <el-button type="primary" @click="showSaveDialog({id:0})">新增角色</el-button>

      <!-- 中间表格 -->
      <el-table :data="roleData" class="table" border empty-text="暂无数据">
        <el-table-column type="index" :index="(index) => (curPage - 1) * pageSize + index + 1" label="序号" width="80" align="center"></el-table-column>
        <el-table-column prop="name" label="角色名" show-overflow-tooltip align="center" width="150" ></el-table-column>
        <el-table-column prop="description" label="角色描述" show-overflow-tooltip align="center"></el-table-column>
        <el-table-column prop="status" label="状态" width="100" align="center"></el-table-column>

        <el-table-column label="操作" class="buttons" width="350" align="center">
          <template slot-scope="scope">
            <el-button type="primary" size="small" @click="showSaveDialog(scope.row)">修改数据</el-button>
            <el-button type="danger" size="small" @click="showDeleteDialog(scope.row)">删除角色</el-button><br>
            <el-button type="info" size="small" class="btn" @click="showAssignPermDrawer(scope.row)">赋予权限</el-button>
            <el-button type="danger" size="small" class="btn" @click="showUnassignPermDrawer(scope.row)">移除权限</el-button><br>
          </template>
        </el-table-column>
      </el-table>

      <!-- 下方分页器 -->
       <el-pagination
        layout="total, sizes, prev, pager, next, jumper"
        :current-page="curPage"
        :page-sizes="pageSizeArr"
        :page-size="pageSize"
        :total="totalRecord"
        @current-change="handleCurrentChange"
        @size-change="handleSizeChange">
      </el-pagination>
    </el-card>

    <!-- 新增或修改用户弹窗 -->
     <el-dialog
      :title="rowRoleId > 0 ? '修改角色' : '新增角色'"
      :visible.sync="isShowSaveDialog"
      width="50%">
      <el-form label-width="80px">
        <el-form-item label="角色名">
          <el-input placeholder="请输入角色名" v-model="roleDataSave.name"></el-input>
        </el-form-item>
        <el-form-item label="角色描述">
          <el-input placeholder="请输入角色描述" v-model="roleDataSave.description"></el-input>
        </el-form-item>
        <el-form-item label="状态">
          <el-radio-group v-model="roleDataSave.status">
            <el-radio :label="1">正常</el-radio>
            <el-radio :label="0">禁用</el-radio>
          </el-radio-group>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click='isShowSaveDialog = false;roleDataSave = {id: 0,name: "",description: "",status: 1};'>取 消</el-button>
        <el-button type="primary" @click="handleSaveRole">确 定</el-button>
      </span>
    </el-dialog>

    <!-- 删除角色弹窗 -->
    <el-dialog
      title="删除角色"
      :visible.sync="isShowDeleteDialog"
      width="50%">
      <span>您确认需要删除此角色？</span>
      <span slot="footer" class="dialog-footer">
        <el-button @click='isShowDeleteDialog = false;'>取 消</el-button>
        <el-button type="primary" @click="handleDeleteRole">确 定</el-button>
      </span>
    </el-dialog>

    <!-- 分配权限抽屉 -->
    <el-drawer title="赋予权限" :visible.sync="isShowAssignPermDrawer">
      <el-form style="padding: 20px">
        <p style="font-size:1.3rem">当前角色：<span class="name">{{  rowRoleDes }}</span></p>
        <el-tree
          style="margin:20px 0;"
          :props="defaultProps"
          :node-key="'id'"
          :data="filteredTreeList"
          :default-expand-all="true"
          :default-checked-keys="defaultCheckedKeys"
          ref="assignTree"
          show-checkbox>
        </el-tree>
        <el-form-item>
          <el-button type="primary" @click="handleAssignPerm">确 定</el-button>
          <el-button @click="isShowAssignPermDrawer = false">取 消</el-button>
        </el-form-item>
      </el-form>
    </el-drawer>

    <!-- 移除权限抽屉 -->
    <el-drawer title="移除权限" :visible.sync="isShowUnassignPermDrawer">
      <el-form style="padding: 20px">
        <p style="font-size:1.3rem">当前角色：<span class="name">{{  rowRoleDes }}</span></p>
        <el-tree
          style="margin:20px 0;"
          :props="defaultProps"
          :node-key="'id'"
          :data="unAssignTreeList"
          :default-expand-all="true"
          empty-text="暂无权限数据,请先添加权限"
          ref="unassignTree"
          show-checkbox>
        </el-tree>
        <template v-if="unAssignTreeList.length > 0">
           <el-form-item>
            <el-button type="primary" @click="handleUnassignPerm">确 定</el-button>
            <el-button @click="isShowUnassignPermDrawer = false">取 消</el-button>
          </el-form-item>
        </template>
      </el-form>
    </el-drawer>

  </div>
</template>

<script>
import {mapActions, mapGetters, mapMutations} from 'vuex';
import { Message } from 'element-ui';

export default {
  name: "RoleView",
  data(){
    return{
      searchRoleName: "",
      roleData: [],
      curPage: 1,
      pageSize: 5,
      pageSizeArr:[5,10,20,30,50],
      totalRecord: 0,
      isShowSaveDialog: false,
      roleDataSave: {
        id: 0,
        name: "",
        description: "",
        status: 1
      },
      isShowDeleteDialog: false,
      isShowAssignPermDrawer: false,
      defaultProps: {
        children: "children",
        label: "title"
      },
      defaultCheckedKeys: [],
      isShowUnassignPermDrawer: false
    }
  },
  methods:{
    //  搜索
    handleSearch(){
      this.curPage = 1;
      this.getRoleData(this.searchRoleName);
    },
    //  重置
    handleReset(){
      this.searchRoleName = "";
      this.curPage = 1;
      this.getRoleData();
    },
    //  分页器
    handleCurrentChange(val) {
      this.curPage = val;
      this.getRoleData();
    },
    handleSizeChange(val) {
      this.pageSize = val;
      this.curPage = 1; 
      this.getRoleData();
    },

    //  获取角色数据
    async getRoleData(name){
      try {
        if (name) {
          this.searchRoleName = name;
        }
        const result = await this.roleList({
          page:this.curPage,
          limit:this.pageSize,
          name: this.searchRoleName
        });
        this.totalRecord = result.total;
        this.roleData = result.data;
      } catch (error) {
        Message({
          type: "error",
          message: error.message
        });
      }
    },

    //  新增或修改角色
    showSaveDialog(obj){
      this.isShowSaveDialog = true;
      this.setRowRoleId(obj.id);
    },
    async handleSaveRole(){
      try{
        if(this.rowRoleId > 0){
          //  更新用户
          this.roleDataSave.id = this.rowRoleId;
          const data = await this.roleUpdate(this.roleDataSave);
          Message({
            type: "success",
            message: data.msg
          });
        } else {
          //  新增用户
          const data = await this.roleAdd(this.roleDataSave);
          Message({
            type: "success",
            message: data.msg
          });
        }
      } catch (error) {
        Message({
          type: "error",
          message: error.message
        });
      } finally {
        this.isShowSaveDialog = false;
        this.roleDataSave = {
          id: 0,
          name: "",
          description: "",
          status: 1
        };
        this.getRoleData();
      }
    },

    //  删除角色
    showDeleteDialog(obj){
      this.isShowDeleteDialog = true;
      this.setRowRoleId(obj.id);
    },
    async handleDeleteRole(){
      try {
        if(this.rowRoleId > 0){
          const data = await this.roleDelete({
            id: this.rowRoleId
          });
          Message({
            type: "success",
            message: data.msg
          });
        }
      } catch (error) {
        Message({
          type: "error",
          message: error.message
        });
      } finally {
        this.isShowDeleteDialog = false;
        this.getRoleData();
      }
    },

    //  赋予权限
    async showAssignPermDrawer(obj){
      this.filteredTreeList = [];
      this.defaultCheckedKeys = [];
      this.isShowAssignPermDrawer = true;
      this.setRowRoleId(obj.id);
      this.setRowRoleDes(obj.description);
      try{
        const rolePerms = await this.rolePermissions({
          role_id: this.rowRoleId
        });
        const allPerms = await this.permissionTreeList();
        await this.getFilteredTreeList([allPerms.data,rolePerms.data.id]);
        this.defaultCheckedKeys = this.getCheckedIdsFromTree(this.filteredTreeList);
      } catch (error){
        Message({
          type: "error",
          message: error.message
        });
      }
    },
    async handleAssignPerm(){
      const checkedKeys = this.$refs.assignTree.getCheckedKeys();
      try{
        if(checkedKeys.length > 0){
          const result = await this.roleAddPermissions({
            role_id: this.rowRoleId,
            perm_id: checkedKeys
          });
           Message({
            type: "success",
            message: result.msg
          });
        }else{
          Message({
            type: "warning",
            message: "请至少选择一个权限"
          });
        }
      }catch(error){
        Message({
          type: "error",
          message: error.message
        });
      }finally{
        this.isShowAssignPermDrawer = false;
        this.getRoleData();
      }
    },
    getCheckedIdsFromTree(tree) {
      let checkedIds = [];
      function traverse(nodes) {
        nodes.forEach(node => {
          if (node.checked === true) {
            checkedIds.push(node.id);
          }
          if (node.children && node.children.length > 0) {
            traverse(node.children);
          }
        });
      }
      traverse(tree);
      return checkedIds;
    },

    //  移除权限
    async showUnassignPermDrawer(obj){
      this.isShowUnassignPermDrawer = true;
      this.setRowRoleId(obj.id);
      this.setRowRoleDes(obj.description);
      try{
        const rolePerms = await this.rolePermissions({
          role_id: this.rowRoleId
        });
        const allPerms = await this.permissionTreeList();
        await this.getUnassignPermTreeList([rolePerms.data,allPerms.data]);
      } catch (error){
        Message({
          type: "error",
          message: error.message
        });
      }
    },
    async handleUnassignPerm(){
      const checkedKeys = this.$refs.unassignTree.getCheckedKeys()
      try{
         if(checkedKeys.length > 0){
          const result = await this.roleDeletePermissions({
            role_id: this.rowRoleId,
            perm_id: checkedKeys
          });
          Message({
            type: "success",
            message: result.msg
          });
        }else{
          Message({
            type: "warning",
            message: "请至少选择一个权限"
          });
        }
      }catch(error){
        Message({
          type: "error",
          message: error.message
        });
      }finally{
        this.isShowUnassignPermDrawer = false;
        this.getRoleData();
      }
    },

    ...mapActions("roleStore",{ 
      roleList: "roleList", 
      roleAdd: "roleAdd", 
      roleUpdate: "roleUpdate",
      roleDelete: "roleDelete",
      rolePermissions:"rolePermissions",
      roleAddPermissions:"roleAddPermissions",
      roleDeletePermissions:"roleDeletePermissions"
    }),
    ...mapActions("permissionStore",{
      permissionTreeList: "permissionTreeList",
      getFilteredTreeList:"getFilteredTreeList",
      getUnassignPermTreeList:"getUnassignPermTreeList"
    }),
    ...mapMutations("roleStore",{
      setRowRoleId: "setRowRoleId",
      setRowRoleDes: "setRowRoleDes"
    })
  },
  mounted(){
    this.getRoleData();
  },
  computed:{
    ...mapGetters("roleStore",{
      rowRoleId: "rowRoleId",
      rowRoleDes: "rowRoleDes",
    }),
    ...mapGetters("permissionStore",{
      filteredTreeList: "filteredTreeList",
      unAssignTreeList: "unAssignTreeList"
    })
  }
}
</script>

<style scoped lang="scss">
.role{
  margin: 0 auto;
  width: 95%;
  .search{
    height: 80px;
    .form{
      display: flex;
      justify-content: space-between;
    }
  }
  .list{
    margin-top: 30px;
    .table{
      margin: 20px 0;
      .btn{
        margin-top: 10px;
      }
    } 
  }
}
.name{
  color: $main_color;
  font-weight: bold;
}
</style>